package edu.neusoft.yiqibike.service.impl;

import com.baomidou.mybatisplus.enums.SqlLike;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import edu.neusoft.yiqibike.common.entity.mysql.Admin;
import edu.neusoft.yiqibike.common.entity.mysql.SystemDictionary;
import edu.neusoft.yiqibike.common.entity.vo.SystemDictionaryVo;
import edu.neusoft.yiqibike.common.exception.ArgumentVerifyException;
import edu.neusoft.yiqibike.common.util.MapperUtil;
import edu.neusoft.yiqibike.dao.mapper.SystemDicMapper;
import edu.neusoft.yiqibike.service.ISystemDictionaryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * User：lyc
 * Date：2018-01-09
 * Time：21:44
 * Description：字典服务实现类
 */
@Slf4j
@Service
public class SystemDictionaryServiceImpl extends ServiceImpl<SystemDicMapper, SystemDictionary> implements ISystemDictionaryService {

    @Override
    public Page<SystemDictionaryVo> getList(Page page) {
        //优先展示父字典
        Wrapper<Object> condition = new EntityWrapper<>();
        //根据code%模糊查询
        if (Objects.nonNull(page) && !MapUtils.isEmpty(page.getCondition())
                && StringUtils.isNotEmpty((String) page.getCondition().get("code"))) {
            condition = condition.like("code", (String) page.getCondition().get("code"), SqlLike.RIGHT);
        }
        List<SystemDictionary> dictionaryList = baseMapper.selectByPage(page, condition);
        if (CollectionUtils.isEmpty(dictionaryList)) {
            page.setRecords(new ArrayList<>());
            return page;
        }
        //给每个子字典设置字典分组（父字典的字典值）
        List<SystemDictionaryVo> voList = new ArrayList<>(dictionaryList.size());
        for (SystemDictionary systemDictionary : dictionaryList) {
            if (Objects.isNull(systemDictionary) && StringUtils.isEmpty(systemDictionary.getGroupId())) {
                continue;
            }
            SystemDictionaryVo vo = new SystemDictionaryVo();
            MapperUtil.getInstance().map(systemDictionary, vo);
            SystemDictionary groupDictionary = baseMapper.select(systemDictionary.getGroupId());
            if (Objects.nonNull(groupDictionary)) {
                vo.setGroup(groupDictionary.getCode());
            }
            voList.add(vo);
        }
        //按照父字典ID进行排序
        voList = voList.stream().sorted()
                .collect(Collectors.toList());
        page.setRecords(voList);
        return page;
    }

    @Override
    public void addOrEditDictionary(SystemDictionary systemDictionary) {
        try {
            systemDictionary.insertOrUpdate();
        } catch (Exception e) {
            throw new ArgumentVerifyException("字典更新失败,请检查字典代码与字典分组是否唯一！");
        }
    }

    @Override
    public List<Map<String, String>> getAllGroups() {
        List<SystemDictionary> dictionaries = new SystemDictionary().selectList(
                new EntityWrapper().eq("is_group", 1));
        if (CollectionUtils.isEmpty(dictionaries)) {
            return Lists.newArrayList();
        }
        List<Map<String, String>> groups = Lists.newArrayList();
        for (SystemDictionary dictionary : dictionaries) {
            Map<String, String> group = ImmutableMap.of("id", dictionary.getId(), "code", dictionary.getCode(),
                    "value", dictionary.getValue());
            groups.add(group);
        }
        return groups;
    }

    @Override
    @Transactional
    public void invertIsEnable(SystemDictionary dictionary, Admin admin) {
        String id = dictionary.getId();
        dictionary = baseMapper.select(id);
        if (Objects.isNull(dictionary)) {
            throw new ArgumentVerifyException("无法找到ID=".concat(id).concat("的字典"));
        }
        Integer isEnable = dictionary.getIsEnable();
        if (isEnable == 1) {
            isEnable = -1;
        } else if (isEnable == -1) {
            isEnable = 1;
        } else {
            throw new IllegalArgumentException("【IP可用状态】：非法");
        }
        Set<String> ids = Sets.newHashSet(id);
        //如果当前字典是父字典且是禁用操作，则保持禁用父字典下的所有子字典
        if (dictionary.getIsGroup() == 1 && dictionary.getIsEnable() == 1) {
            List<SystemDictionary> dictionaries = this.getDictionaryByGroup(dictionary.getCode());
            if (!CollectionUtils.isEmpty(dictionaries)) {
                //将所有可用的子字典加入待更新集合中
                ids.addAll(dictionaries.stream().filter(systemDictionary -> systemDictionary.getIsEnable() == 1)
                        .map(SystemDictionary::getId).collect(Collectors.toSet()));
            }
        }
        baseMapper.updateIsEnableByIds(ids, isEnable, new Date(), Objects.nonNull(admin) ? String.valueOf(admin.getId()) : "未知");
    }

    @Override
    @Transactional
    public void remove(List<String> ids) {
        List<SystemDictionary> dictionaries = baseMapper.selectByIds(ids);
        if (CollectionUtils.isEmpty(dictionaries)) {
            return;
        }
        //过滤出待删除列表中所有的父节点
        dictionaries.stream().filter(dictionary -> dictionary.getIsGroup() == 1)
                .forEach(dictionary -> {
                    //将每个父节点下的所有子字典添加至待删除列表中
                    List<SystemDictionary> dictionaryList = baseMapper.selectByGroupId(dictionary.getId());
                    if (!CollectionUtils.isEmpty(dictionaryList)) {
                        ids.addAll(dictionaryList.stream().map(SystemDictionary::getId).collect(Collectors.toSet()));
                    }
                });
        baseMapper.deleteBatchByIds(ids);
    }

    /**
     * 根据分组标识的字典代码获取其下的所有字典
     *
     * @param group 分组标识
     * @return 字典列表
     */
    @Override
    public List<SystemDictionary> getDictionaryByGroup(String group) {
        //根据分组代码获取分组ID
        SystemDictionary groupDictionary = new SystemDictionary().selectOne(new EntityWrapper().eq("code", group)
                .isNull("group_id").eq("is_group", 1));
        if (Objects.isNull(groupDictionary)) {
            throw new ArgumentVerifyException("分组字典不存在：".concat(group));
        }
        //获取分组下的所有字典
        List<SystemDictionary> dictionaryList = groupDictionary.selectList(
                new EntityWrapper().eq("group_id", groupDictionary.getId()));
        return CollectionUtils.isEmpty(dictionaryList) ? Lists.newArrayList() : dictionaryList;
    }

    /**
     * 根据分组标识的字典值与字典代码获取字典值
     *
     * @param code      字典代码
     * @param groupCode 分组标识
     * @return 字典值
     */
    @Override
    public SystemDictionary getByCodeAndGroupCode(String code, String groupCode) {
        return baseMapper.selectByCodeAndGroupCode(code, groupCode);
    }

    @Override
    public Page<SystemDictionaryVo> getGroupsByCode(Page page, String id) {
        List<SystemDictionaryVo> dictionaryVos = baseMapper.selectUnion(page, id);
        if (CollectionUtils.isNotEmpty(dictionaryVos)) {
            //过滤获取父节点的CODE
            Optional<String> group = dictionaryVos.stream()
                    .filter(vo -> vo.getIsGroup() == 1 && Objects.isNull(vo.getGroupId()))
                    .map(SystemDictionary::getCode).findAny();
            if (group.isPresent()) {
                //遍历所有子节点标记其父节点的CODE
                for (SystemDictionaryVo vo : dictionaryVos) {
                    if (vo.getIsGroup() == 1) {
                        continue;
                    }
                    vo.setGroup(group.get());
                }
            }
            page.setRecords(dictionaryVos);
        }
        return page;
    }
}
